package distanceMatrix;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Hashtable;

public class DistanceMatrixUtils {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		if(args.length>0){
			if(args[0].equals("stat_water_needle")&&args.length==3){
				stat_water_needle(args[1], args[2]);
			}
		}else{
			System.out.println(getHelp());
			System.exit(616);
		}
	}

	private static String getHelp(){
		String help="Reads and manipulates distancematrices of different kinds\n";
		help+="stat_water_needle - gives max and average identity for all transkripts against reference groups (excluding self?) defined by a tab-separated file (id\tgroup)\n";
		help+="\tusage: stat_water_needle <water_needle_expanded_file> <group_file>\n";
		help+="\n";
		
		return help;
	}
	public static void stat_water_needle(String dmFile,String groupFile)throws Exception{
		DistanceMatrix dm=new DistanceMatrix("extended_water_needle",dmFile);
		Hashtable<String, ArrayList<String>> groups=new Hashtable<String, ArrayList<String>>();
		BufferedReader in=new BufferedReader(new FileReader(groupFile));
		//get reference groups and store them in a Hashtable
		for(String s=in.readLine();s!=null;s=in.readLine()){
			String[] l=s.split("\t");
			if(l.length>1){
				if(!groups.containsKey(l[1])){
					groups.put(l[1], new ArrayList<String>());
				}
				ArrayList<String> tmp=groups.get(l[1]);
				if(!tmp.contains(l[0])){
					tmp.add(l[0]);
				}
			}
		}
		//print header
		Object[] groupNames=groups.keySet().toArray();
		String[] stats=new String[]{"max_id","closest_relative","avg_id"};
		System.out.print("\t\t\t\t\t"+groupNames[0]);
		for(int i=1;i<groupNames.length;i++){
			for(int j=0;j<stats.length;j++){
				System.out.print("\t");
			}
			System.out.print((String)groupNames[i]);
		}
		System.out.print("\nid\tmax_max\tmax_max_group\tmax_avg\tmax_avg_group");
		for(int i=0;i<groupNames.length;i++){
			for(int j=0;j<stats.length;j++){
				System.out.print("\t"+stats[j]);
			}
		}
		System.out.println();
		//make calculations and print result
		int antal;
		double max,sum,identity,max_max,max_avg;
		String out,closest_relative,max_max_group,max_avg_group;
		for (String id1 : dm.getNames()) {
			out="";
			max_max=Double.NEGATIVE_INFINITY;
			max_avg=Double.NEGATIVE_INFINITY;
			max_max_group="";
			max_avg_group="";
			for (Object group : groupNames) {
				max=Double.NEGATIVE_INFINITY;
				sum=0;
				antal=0;
				closest_relative="";
				for (String id2 : groups.get(group)) {
					if(!id1.equals(id2)&&dm.getNames().contains(id2)){
						antal++;
						identity=dm.getIdentity(id1, id2);
						sum+=identity;
						if(identity>max){
							closest_relative=id2;
							max=identity;
						}
					}
				}
				if(antal>2&&sum/antal>max_avg){
					max_avg=sum/antal;
					max_avg_group=(String)group;
				}
				if(max>max_max){
					max_max=max;
					max_max_group=(String)group;
				}
				out+="\t"+max+"\t"+closest_relative+"\t"+(sum/antal);
			}
			System.out.println(id1+"\t"+max_max+"\t"+max_max_group+"\t"+max_avg+"\t"+max_avg_group+out);
		}
	}
}
